package com.study.talk.common.code;


import com.study.talk.common.serializer.Serializer;
import com.study.talk.module.netty.message.MessageType;
import com.study.talk.module.netty.message.TalkMessage;
import com.study.talk.module.netty.message.request.*;
import com.study.talk.module.netty.message.response.*;
import io.netty.buffer.ByteBuf;

public class MessageCode {

    public static final MessageCode INSTANCE = new MessageCode();

    private MessageCode() {
    }

    public static final int MAGIC_NUMBER = 0x12345678;

    public void encode(ByteBuf byteBuf, TalkMessage message) {
        byte[] bytes = Serializer.Default.serializer(message);
        //魔数
        byteBuf.writeInt(MAGIC_NUMBER);
        //版本
        byteBuf.writeByte(message.getVersion());
        //序列化方式
        byteBuf.writeByte(Serializer.Default.getSerializerAlgorithm());
        //消息类型
        byteBuf.writeByte(message.getType());
        //消息长度
        byteBuf.writeInt(bytes.length);
        byteBuf.writeBytes(bytes);
    }

    public TalkMessage decode(ByteBuf byteBuf) {
        //跳过魔术
        byteBuf.skipBytes(4);
        //跳过版本
        byteBuf.skipBytes(1);
        // 序列化算法
        byte serializeAlgorithm = byteBuf.readByte();
        // 消息类型
        byte MessageType = byteBuf.readByte();
        //长度
        int length = byteBuf.readInt();
        byte[] bytes = new byte[length];
        byteBuf.readBytes(bytes);
        Class<? extends TalkMessage> messageClass = getPacketByMessageType(MessageType);
        Serializer serializer = getSerializer(serializeAlgorithm);
        return serializer.deSerializer(messageClass, bytes);

    }

    public static Class<? extends TalkMessage> getPacketByMessageType(byte type) {
        switch (type) {
            case MessageType.LOGIN_REQUEST:
                return LoginRequest.class;
            case MessageType.LOGIN_RESPONSE:
                return LoginResponse.class;
            case MessageType.SEND_MESSAGE_RESPONSE:
                return MessageResponse.class;
            case MessageType.ADD_USER_REQUEST:
                return AddUserRequest.class;
            case MessageType.ADD_USER_RESPONSE:
                return AddUserResponse.class;
            case MessageType.ADD_USER_SELF_RESPONSE:
                return AddUserSelfResponse.class;
            case MessageType.CREATE_GROUP_REQUEST:
                return CreateGroupRequest.class;
            case MessageType.CREATE_GROUP_RESPONSE:
                return CreateGroupResponse.class;
            case MessageType.INVITE_GROUP_REQUEST:
                return InviteGroupRequest.class;
            case MessageType.INVITE_GROUP_RESPONSE:
                return InviteGroupResponse.class;
            case MessageType.INVITE_GROUP_SELF_RESPONSE:
                return InviteGroupSelfResponse.class;
            case MessageType.GROUP_MESSAGE_REQUEST:
                return GroupMessageRequest.class;
            case MessageType.GROUP_MESSAGE_RESPONSE:
                return GroupMessageResponse.class;
            case MessageType.ACCEPT_GROUP_REQUEST:
                return AcceptGroupRequest.class;
            case MessageType.ACCEPT_GROUP_RESPONSE:
                return AcceptGroupResponse.class;
            case MessageType.ACCEPT_REQUEST:
                return AcceptRequest.class;
            case MessageType.ACCEPT_RESPONSE:
                return AcceptResponse.class;
            case MessageType.REGISTER_REQUEST:
                return RegisterRequest.class;
            case MessageType.REGISTER_RESPONSE:
                return RegisterResponse.class;
//            case MessageType.UPDATE_PASSWD_REQUEST :
//                return UpdatePasswdRequest.class;
//            case MessageType.UPDATE_PASSWD_RESPONSE :
//                return UpdatePasswdResponse.class;
            case MessageType.MESSAGE_SELF_RESPONSE:
                return MessageSelfResponse.class;
            case MessageType.HEAT_BEAT_REQUEST:
                return HeartBeatRequest.class;
            case MessageType.HEAT_BEAT_RESPONSE:
                return HeartBeatResponse.class;
            case MessageType.SYNC_MESSAGE_REQUEST:
                return SyncMessageRequest.class;
            case MessageType.APPLY_GROUP_REQUEST:
                return ApplyGroupRequest.class;
            case MessageType.APPLY_GROUP_RESPONSE:
                return ApplyGroupResponse.class;
            case MessageType.APPLY_GROUP_SELF_RESPONSE:
                return ApplyGroupSelfResponse.class;
            case MessageType.ACCEPT_JOIN_GROUP_REQUEST:
                return AcceptJoinGroupRequest.class;
            case MessageType.ACCEPT_JOIN_GROUP_RESPONSE:
                return AcceptJoinGroupResponse.class;
            case MessageType.SEND_SMS_REQUEST:
                return SmsSendRequest.class;
            case MessageType.SEND_SMS_RESPONSE:
                return SmsSendResponse.class;
            case MessageType.GROUP_MESSAGE_SELF_RESPONSE:
                return GroupMessageSelfResponse.class;
            default:
                return MessageRequest.class;
        }
    }

    private Serializer getSerializer(byte serializeAlgorithm) {
        return Serializer.Default;
    }
}
